package com.arvato.common.https;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.arvato.minipro.bean.bean_do.wx.OpenPlatformAuthDo;
import com.arvato.minipro.bean.bean_dto.common.Result;
import com.arvato.minipro.bean.bean_dto.wx.ExtJson;
import com.arvato.minipro.bean.bean_dto.wx.PageInfo;
import com.arvato.minipro.bean.bean_vo.wx.OpenPlatformAuthVo;
import com.arvato.common.config_bean.WxPlatformConfig;
import com.arvato.common.ftp.FtpTool;
import com.arvato.common.redis.RedisUtil;
import com.arvato.common.util.ContantFinalUtil;
import com.arvato.common.util.JsonUtil;
import com.arvato.minipro.service.user.OpenPlatformAuthService;
/**
 * 
 * @author: smallking
 * 
 * @Descibe:微信小程序或者是三方开放平台和微信服务器请求交互的工具类
 * 
 * @Date: 2018年8月2日  下午2:45:31
 */
@Component
public class WxMiniproThirdRequestUtil {
	private Logger logger = LoggerFactory.getLogger(WxMiniproThirdRequestUtil.class);
	@Autowired
	private RedisUtil redisUtil;
	
	@Autowired
	private FtpTool ftpTool;
	
	@Autowired
	private JsonUtil jsonUtil;
	
	@Autowired
	private OpenPlatformAuthService openPlatformAuthService;
	
	/**
	 * 获取第三方平台和微信交互的访问令牌
	 * 当token失效或者token不存在的时候，主动调用此方法，如果请求失败 则返回false，告诉调用者 稍后再试。
	 * @param req
	 * @return 200 请求成功
	 * @return 201 component_verify_ticket 不存在或者过期
	 * @return 500 未知原因请求失败 具体查看微信返回值
	 */
	public synchronized Result getComponentAccessToken() {
		Result result = new Result(false);
		String accessToken = redisUtil.get("component_access_token");
		// 如果当前缓存里面有token 直接返回
		if(accessToken != null) {
			result.setResult(true);
			result.setData(accessToken);
			logger.info("redis缓存中存在三方和微信交互的令牌");
			return result;
		}
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
		// 拼装请求参数json
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
	    paramJson.put("component_appsecret", WxPlatformConfig.WX_SECRET);
	    // 获取微信推送的最新的verifyTicket（十分钟推送一次）
	    Object ticket = redisUtil.get("component_verify_ticket");
	    // 如果ticket为空 则返回获取token失败
		if(ticket == null || ticket.equals("")) {
			result.setCode(201);
			logger.info("获取三方和微信交互的访问令牌失败");
			return result;
		}
		paramJson.put("component_verify_ticket", ticket.toString());
	    String jsonStr = jsonUtil.obj2String(paramJson);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonStr);
		logger.info("请求componet_token的json参数字符串:" + jsonStr);
		logger.info("请求微信componet_token返回的字符串:" + respJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("component_access_token") != null) {
			String token = map.get("component_access_token") + "";
			redisUtil.set("component_access_token", token.toString(), 7000);
			result.setResult(true);
			result.setData(token.toString());
			logger.info("获取三方和微信交互的访问令牌成功");
			return result;
		}
		return result;
	}
	/**
	 * 发送请求获取预授权码
	 * @return
	 */
	public synchronized Result getPreAuthCode() {
		Result result = new Result(false);
		if(redisUtil.get("pre_auth_code") != null) {
			result.setData(redisUtil.get("pre_auth_code"));
			result.setResult(true);
			return result;
		}
		result = getComponentAccessToken();
		// 如果访问令牌过期了或者不存在直接返回
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token="
		+ accessToken.toString();
		// 请求参数map
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		logger.info("请求预授权码返回的字符串:" + respJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("pre_auth_code") != null) {
			String preAuthCode = map.get("pre_auth_code") + "";
			redisUtil.set("pre_auth_code", preAuthCode.toString(), 550);
			result.setResult(true);
			result.setData(preAuthCode.toString());
		}else {
			result.setResult(false);
		}
		return result;
	}
	/**
	 * 刷新预授权码：一些时候，一个授权码被授权使用过了之后，第二个人授权的话，会提示：
	 * 当前授权码已经被使用过，请更换授权码。所以在授权成功的回调里面，调用这个方法。
	 * @return
	 */
	public Result refreshPreAuthCode() {
		Result result = getComponentAccessToken();
		// 如果访问令牌过期了或者不存在直接返回
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token="
		+ accessToken.toString();
		// 请求参数map
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		logger.info("请求预授权码返回的字符串:" + respJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("pre_auth_code") != null) {
			String preAuthCode = map.get("pre_auth_code") + "";
			redisUtil.set("pre_auth_code", preAuthCode.toString(), 550);
			result.setResult(true);
			result.setData(preAuthCode.toString());
		}
		return null;
	}
	
	/**
	 * 根据授权码获取访问已授权用户的访问令牌和刷新令牌
	 * authorizer_access_token和authorizer_refresh_token
	 * @param authCode 用户授权回调 微信传的授权码
	 * @return
	 */
	public Result getAuthAccessToken(String authCode) {
		Result result = getComponentAccessToken();
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=" + accessToken;
		// 拼接请求参数json字符串
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
	    paramJson.put("authorization_code", authCode);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		logger.info("请求authorizer_access_token的返回信息：" + respJsonStr);
		// 将json转换成对象 存储在数据库里面
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("authorization_info")!= null) {
			@SuppressWarnings("unchecked")
			Map<String, Object> authInfoMap = (Map<String, Object>)map.get("authorization_info");
			// 如果授权成功了 以authorizer_appid为键authorizer_access_token为值 放到redis里面 有效期设置为7000秒
			redisUtil.set(authInfoMap.get("authorizer_appid").toString(), authInfoMap.get("authorizer_access_token").toString(), 7000);
			// 同时将用户授权信息存到数据库 刷新令牌authorizer_refresh_token主要用于第三方平台获取和刷新已授权用户的access_token，只会在授权时刻提供，请妥善保存
			OpenPlatformAuthDo userAuthDo = new OpenPlatformAuthDo();
			userAuthDo.setAuthorizerAppid(authInfoMap.get("authorizer_appid").toString());
			userAuthDo.setAuthorizerRefreshToken(authInfoMap.get("authorizer_refresh_token").toString());
			userAuthDo.setFuncInfo(authInfoMap.get("func_info").toString());
			userAuthDo.setLastAuthTime(new Date());
			userAuthDo.setThirdPartyAppid(WxPlatformConfig.WX_APPID);
			// 先查询当前数据库里面是否有当前用户的授权信息 如果有的话就更新 没有就新增
			OpenPlatformAuthVo userAuthVo = openPlatformAuthService.getUserAuthByAppId(authInfoMap.get("authorizer_appid").toString());
			try {
				if(userAuthVo != null) {
					userAuthDo.setUserAuthId(userAuthVo.getUserAuthId());
					// 更新
					openPlatformAuthService.update(userAuthDo);
				}else {
					userAuthDo.setCreateTime(new Date());
					// 新增 
					openPlatformAuthService.insert(userAuthDo);
					// 然后自动执行 设置域名 设置体验人员 
					String authorizerAppid = userAuthDo.getAuthorizerAppid();
					this.workDomain(authorizerAppid, "add");
					this.webDomain(authorizerAppid, "add");
					this.testerMar(authorizerAppid, "XKingBlue", "bind");
					this.testerMar(authorizerAppid, "smallking-blue", "bind");
					// 查询小程序的所有模板 获取最新的模板ID 提交代码 
					String templateId = getNewestTemplate();
					logger.info("最新模板Id是：" + templateId);
					this.codeCommit(userAuthDo.getAuthorizerAppid(), getNewestTemplate());
				}
			} catch (Exception e) {
				logger.info("userAuthService插入失败", e);
				e.printStackTrace();
			}
			result.setData(userAuthDo.getAuthorizerAppid());
		}else {
			result.setResult(false);
			logger.info("请求微信的返回值不包含，authToken" + respJsonStr);
		}
		return result;
	}
	/**
	 * 根据刷新令牌authorizer_refresh_token获得新的authorizer_access_token
	 * @param authorizerAppID 授权方的AppId
	 * @return
	 */
	public Result refreshAuthAccessToken(String authorizerAppID) {
		// 查询当前的appid是否曾经授权过给我们
		OpenPlatformAuthVo userAuthVo = openPlatformAuthService.getUserAuthByAppId(authorizerAppID);
		if(userAuthVo == null) {
			return new Result(false);
		}
		Result result = getComponentAccessToken();
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=" + accessToken;
		// 拼接请求参数
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
	    paramJson.put("authorizer_appid", userAuthVo.getAuthorizerAppid());
	    paramJson.put("authorizer_refresh_token", userAuthVo.getAuthorizerRefreshToken());
		logger.info("刷新小程序授权码的参数json：" + jsonUtil.obj2String(paramJson));
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		logger.info("刷新小程序授权码返回信息：" + respJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("authorizer_access_token") != null) {
			// 将请求刷新的token放到缓存里面
			redisUtil.set(authorizerAppID, map.get("authorizer_access_token").toString(), 7000);
			result.setData(map.get("authorizer_access_token"));
		}else {
			result.setResult(false);
		}
		return result;
	}
	/**
	 * 获取授权微信用户信息
	 * @param authorizerAppID
	 * @return
	 */
	public Result getAutherInfo(String authorizerAppID) {
		Result result = getComponentAccessToken();
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=" + accessToken;
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
	    paramJson.put("authorizer_appid", authorizerAppID);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("authorizer_info") != null) {
			result.setData(respJsonStr);
		}else {
			result.setResult(false);
		}
		logger.info(respJsonStr);
		return result;	
	}
	/**
	 * 查询当前平台下 所有的授权方信息
	 * @return
	 */
	public Result listAutherInfo() {
		Result result = getComponentAccessToken();
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_list?component_access_token=" + accessToken;
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("component_appid", WxPlatformConfig.WX_APPID);
	    paramJson.put("offset", 0);
	    paramJson.put("count", 499);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("list") != null) {
			logger.info(map.get("list").toString());
			result.setData(map.get("list"));
		}else {
			result.setResult(false);
		}
		return result;	
	}
	/**
	 * 设置查询修改小程序的服务器域名
	 * @param authorizerAppID
	 * @return
	 */
	public Result webDomain(String authorizerAppID, String action) {
		// 授权码 
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			Result result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		Result result = new Result(false);
		String url = "https://api.weixin.qq.com/wxa/modify_domain?access_token=" + accessToken;
		// 拼接请求参数
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("action", action);
	    String[] requestdomain = {"https://minipro.arvatocrm.cn"};
	    String[] wsrequestdomain = {"wss://minipro.arvatocrm.cn"};
	    String[] uploaddomain = {"https://minipro.arvatocrm.cn"};
	    String[] downloaddomain = {"https://minipro.arvatocrm.cn"};
	    paramJson.put("requestdomain", requestdomain);
	    paramJson.put("wsrequestdomain", wsrequestdomain);
	    paramJson.put("uploaddomain", uploaddomain);
	    paramJson.put("downloaddomain", downloaddomain);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		logger.info("请求设置小程序服务器域名返回json：" + respJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map == null || !"0".equals(map.get("errcode").toString())) {
			result.setResult(false);
		}
		return result;
	}
	/**
	 * 设置查询修改小程序的业务服务器域名
	 * @param authorizerAppID
	 * @return
	 */
	public Result workDomain(String authorizerAppID, String action) {
		// 授权码 
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			Result result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		Result result = new Result(false);
		String url = "https://api.weixin.qq.com/wxa/setwebviewdomain?access_token=" + accessToken;
		// 拼接请求参数
		Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("action", action);
	    String[] webviewdomain = {"https://minipro.arvatocrm.cn"};
	    paramJson.put("webviewdomain", webviewdomain);
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramJson));
		logger.info("请求设置小程序业务域名返回信息：" + respJsonStr + "--" + jsonUtil.obj2String(paramJson));
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map == null || !"0".equals(map.get("errcode").toString())) {
			result.setResult(false);
		}
		return result;
	}
	
	/**
	 * 帮助已授权小程序提交代码
	 * @param authorizerAppID
	 * @param templateId
	 * @return
	 */
	public Result codeCommit(String authorizerAppID, String templateId) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/commit?access_token=" + accessToken;
		// ext_json的window配置
		Map<String, Object> windowMap = new HashMap<String, Object>();
	    windowMap.put("backgroundTextStyle", "light");
	    windowMap.put("navigationBarBackgroundColor", "#F9F9F9");
	    windowMap.put("navigationBarTitleText", "欧唯特");
	    windowMap.put("navigationBarTextStyle", "black");
		// ext_json的自定义参数
	    Map<String, String> extMap = new HashMap<String, String>();
	    extMap.put("appId", authorizerAppID);
	    // ext_json的界面配置
	    Map<String, PageInfo> pagesMap = new LinkedHashMap<String, PageInfo>();
	    pagesMap.put("pages/index/index", new PageInfo("欧唯特"));
	    pagesMap.put("pages/mall/cut/cut", new PageInfo("欧唯特"));
	    pagesMap.put("pages/mall/index_wz/index_wz", new PageInfo("欧唯特"));
	    pagesMap.put("pages/mall/store/store", new PageInfo("地图门店"));
	    pagesMap.put("pages/mall/store_info/store_info", new PageInfo("地图门店"));
	    pagesMap.put("pages/error/error", new PageInfo("error"));
	    pagesMap.put("pages/mall/list/commodity_list", null);
	    pagesMap.put("pages/mall/order_list/order_list", new PageInfo("订单列表页"));
	    pagesMap.put("pages/mall/order_info/order_info", new PageInfo("订单详情页"));
	    pagesMap.put("pages/mall/order/order", new PageInfo("订单页"));
	    pagesMap.put("pages/mall/address_list/address_list", new PageInfo("我的地址"));
	    pagesMap.put("pages/mall/address/address", new PageInfo("我的地址"));
	    pagesMap.put("pages/mall/user_info/user_info", new PageInfo("个人信息"));
	    pagesMap.put("pages/mall/user/user", new PageInfo("用户中心"));
	    pagesMap.put("pages/mall/cart/cart", new PageInfo("购物车"));
	    pagesMap.put("pages/mall/detail/commodity_detail", new PageInfo("详情页"));
	    pagesMap.put("pages/mall/test/test", new PageInfo("测试"));
	    pagesMap.put("pages/mall/bonus/bonus", new PageInfo("积分流水"));
	    pagesMap.put("pages/survey/bobbi/index", new PageInfo("问卷"));


	    pagesMap.put("pages/wxwork/index/index", new PageInfo("资生堂"));
	    pagesMap.put("pages/wxwork/user/user", new PageInfo("个人中心"));
	    pagesMap.put("pages/wxwork/cate/index/index", new PageInfo("内容词典"));
	    pagesMap.put("pages/wxwork/cate/message/message", new PageInfo("信息编辑"));
	    pagesMap.put("pages/wxwork/cate/activity/activity", new PageInfo("商场活动"));
	    pagesMap.put("pages/wxwork/cate/vip/vip", new PageInfo("会员权益"));
	    pagesMap.put("pages/wxwork/cate/invite/invite-list/invite-list", new PageInfo("邀约话术"));
	    pagesMap.put("pages/wxwork/cate/invite/invite-detail/invite-detail", new PageInfo("话术详情"));
	    pagesMap.put("pages/wxwork/recruit/recruit", new PageInfo("招募客户"));
	    pagesMap.put("pages/wxwork/mailList/mailList", new PageInfo("客户通讯录"));
	    pagesMap.put("pages/wxwork/personal/personal", new PageInfo("客户详情"));
	    pagesMap.put("pages/wxwork/cate/activityDetail/activityDetail", new PageInfo("活动详情"));
	    
	    // ext_json的界面列表
	    List<String> pageList = new ArrayList<String>();
	    for(String name : pagesMap.keySet()) {
			pageList.add(name);
		}
	    // ext的pages 在ExtJson类的get set方法做了处理
	    ExtJson extJson = new ExtJson();
	    extJson.setExtAppid(authorizerAppID);
	    extJson.setExt(extMap);
	    extJson.setExtPages(pagesMap);
	    extJson.setPages(pageList);
	    extJson.setWindow(windowMap);
	    String extJsonStr = jsonUtil.obj2String(extJson);
	    
	    Map<String, Object> paramJson = new HashMap<String, Object>();
	    paramJson.put("template_id", templateId);
	    paramJson.put("user_version", "V2.0.1");
	    paramJson.put("user_desc", "欧唯特小程序");
	    paramJson.put("ext_json", extJsonStr);
	    String paramJsonStr = jsonUtil.obj2String(paramJson);
	    logger.info("请求提交小程序代码参数字符串" + paramJsonStr);
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", paramJsonStr);
	    logger.info("请求提交小程序代码URL：" + url + "返回值：" + respJsonStr + "--参数：" + paramJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && "0".equals(map.get("errcode").toString())) {
			result.setResult(true);
		}
		return result;
	}
	/**
	 * 获得小程序体验码
	 * @param authorizerAppID
	 * @param path
	 * @return
	 */
	public Result getQRCode(String authorizerAppID, String path) {
		Result result = new Result(false);
		// 先查询本地数据库 看看该小程序是不是已经有过授权码保存在本地了
		OpenPlatformAuthVo userAuthVo = openPlatformAuthService.getUserAuthByAppId(authorizerAppID);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/get_qrcode?access_token=" + accessToken;
	    InputStream inputStream = HttpsUtil.httpsDownload(url, "GET", null);
		String fileName = System.currentTimeMillis() + ".jpg";
		boolean flag = ftpTool.uploadFile(inputStream, fileName);
		if(flag) {
			// 文件上传成功之后 其路径存储在数据库
			OpenPlatformAuthDo userAuthDo = new OpenPlatformAuthDo();
			userAuthDo.setUserAuthId(userAuthVo.getUserAuthId());
			userAuthDo.setQrCode(fileName);
			int row = openPlatformAuthService.update(userAuthDo);
			if(row == 1) {
				String qrCode = userAuthVo.getQrCode();
				if(qrCode != null) {
					// 如果之前有 就删掉之前的
					ftpTool.delete(qrCode);
				}
			}
			logger.info("请求小程序体验码成功，文件名是：" + fileName);
			result.setResult(true);
			result.setData(ContantFinalUtil.IMG_PATH + "?fileName=" + fileName); 
		}else {
			logger.info("小程序体验码上传到ftp失败");
		}
	    return result;
	}
	
	/**
	 * 发送请求 获取小程序的二级类目及用于代码审核的可选三级类目。
	 * @param authorizerAppID
	 * @return
	 */
	public Result getCategory(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/get_category?access_token=" + accessToken;
	    String respJsonStr = HttpsUtil.httpsRequest(url, "GET", null);
	    logger.info("请求小程序的类目的URL：" + url + "返回值:" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && "0".equals(map.get("errcode").toString())) {
			result.setResult(true);
			result.setData(map.get("category_list"));
		}
	    return result;
	}
	
	/**
	 * 获取小程序的第三方提交代码的页面配置（仅供第三方开发者代小程序调用）
	 * @param authorizerAppID
	 * @return
	 */
	public Result getPageList(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/get_page?access_token=" + accessToken;
	    String respJsonStr = HttpsUtil.httpsRequest(url, "GET", null);
	    logger.info("请求小程序的页面配置的URL：" + url + "返回值:" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && "0".equals(map.get("errcode").toString())) {
			result.setResult(true);
			result.setData(map.get("page_list"));
		}
	    return result;
	}
	
	/**
	 * 管理小程序的体验人员
	 * @param authorizerAppID 小程序ID
	 * @param wechatid 微信号ID
	 * @param action：bind 增加；unbind 删除
	 * @return
	 */
	public Result testerMar(String authorizerAppID, String wechatid, String action) {
		Result result = new Result();
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/" + action + "_tester?access_token=" + accessToken;
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("wechatid", wechatid);
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramMap));
	    logger.info("请求添加小程序体验人员的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 得到当前第三方平台的所有模板
	 * @return
	 */
	public Result getTemplateList() {
		Result result = getComponentAccessToken();
		// 如果访问令牌过期了或者不存在直接返回
		if(result.getCode() != 200) {
			return result;
		}
		String accessToken = result.getData().toString();
		String url = "https://api.weixin.qq.com/wxa/gettemplatelist?access_token="
		+ accessToken.toString();
		// 请求参数map
		String respJsonStr = HttpsUtil.httpsRequest(url, "POST", null);
		logger.info("请求当前小程序模板列表返回的json字符串:" + respJsonStr);
		Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
		if(map != null && map.get("template_list") != null) {
			@SuppressWarnings("unchecked")
			List<Map<String, Object>> templateList = (List<Map<String, Object>>) map.get("template_list");
			result.setResult(true);
			result.setData(templateList);
		}else {
			result.setResult(false);
		}
		return result;
	}

	/**
	 * 获取最新的模板
	 * @return
	 */
	public String getNewestTemplate() {
		Result result = getTemplateList();
		if(result.getCode() == 200) {
			@SuppressWarnings("unchecked")
			List<Map<String, Object>> templateList = (List<Map<String, Object>>) result.getData();
			return templateList.get(templateList.size() - 1).get("template_id").toString();
		}
		return null;
	}
	
	/**
	 * 代码提交审核
	 * @param authorizerAppID
	 * @return
	 */
	public Result submitAudit(String authorizerAppID){
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/submit_audit?access_token="
		+ accessToken.toString();
		// TODO 首先获取该小程序的可选类目，暂时先走通 写死。 以后需要商户来自己定义 或者我们灵活配置
		// 请求参数拼装
		Map<String, Object> paramMap = new HashMap<String, Object>();
		List<Map<String, Object>> itemList = new ArrayList<Map<String, Object>>();
		Map<String, Object> item1 = new HashMap<String, Object>();
		item1.put("address", "pages/mall/list/commodity_list");
		item1.put("tag", "化妆品 护肤");
		item1.put("first_class", "商家自营");
		item1.put("second_class", "美妆/洗护");
		item1.put("first_id", 304);
		item1.put("second_id", 786);
		item1.put("title", "商品列表");
		
		Map<String, Object> item2 = new HashMap<String, Object>();
		item2.put("address", "pages/mall/cart/cart");
		item2.put("tag", "化妆品 护肤");
		item2.put("first_class", "商家自营");
		item2.put("second_class", "美妆/洗护");
		item2.put("first_id", 304);
		item2.put("second_id", 786);
		item2.put("title", "购物车");
		
		itemList.add(item1);
		itemList.add(item2);
		paramMap.put("item_list", itemList);
		
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramMap));
	    logger.info("请求提交审核小程序的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	// TODO 暂时手动记住审核编号 后面的话要将auditid存储在数据库 暂时存缓存了
			redisUtil.set(authorizerAppID + "audit_id", map.get("auditid").toString(), 72000);
	    	result.setData(map.get("auditid"));
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 得到最近提交的版本的审核状态
	 * @param authorizerAppID
	 * @return
	 */
	public Result getAuditResult(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/get_latest_auditstatus?access_token="
		+ accessToken.toString();
		
	    String respJsonStr = HttpsUtil.httpsRequest(url, "GET", null);
	    logger.info("请求提交审核小程序的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	// TODO 暂时手动记住审核编号 后面的话要将auditid存储在数据库 暂时存缓存了
	    	result.setData(map.get("auditid") + respJsonStr);
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	
	}
	
	/**
	 * 发布小程序
	 * @param authorizerAppID
	 * @return
	 */
	public Result release(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/wxa/release?access_token="
		+ accessToken.toString();
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", "{}");
	    logger.info("请求发布小程序的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 设置小程序“扫普通链接二维码打开小程序”
	 * 增加或修改二维码规则
	 * @param authorizerAppID
	 * @return
	 */
	public Result setQRCodeRegular(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumpadd?access_token="
				+ accessToken.toString();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("prefix", "https://minipro.arvatocrm.cn/arvato/index.html");
		paramMap.put("permit_sub_rule", "2");
		paramMap.put("path", "pages/index/index");
		paramMap.put("open_version", "3");
		// 0代表增加 1代表修改
		paramMap.put("is_edit", "1");
		List<String> debugUrlList = new ArrayList<String>();
		debugUrlList.add("https://minipro.arvatocrm.cn/arvato/index.html?method=1");
		debugUrlList.add("https://minipro.arvatocrm.cn/arvato/index.html?method=2");
		debugUrlList.add("https://minipro.arvatocrm.cn/arvato/index.html?method=3");
		debugUrlList.add("https://minipro.arvatocrm.cn/arvato/index.html?method=4");
		debugUrlList.add("https://minipro.arvatocrm.cn/arvato/index.html?method=5");
		paramMap.put("debug_url", debugUrlList);
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramMap));
	    logger.info("请求增加或修改二维码规则的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 设置小程序“扫普通链接二维码打开小程序”
	 * 得到所有已经设置的二维码规则
	 * @param authorizerAppID
	 * @return
	 */
	public Result getQRCodeRegular(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumpget?access_token="
				+ accessToken.toString();
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", "{}");
	    logger.info("请求得到所有二维码规则的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null) {
	    	result.setResult(true);
	    	result.setData(map.get("rule_list"));
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 删除二维码的规则
	 * @param authorizerAppID
	 * @return
	 */
	public Result deleteQRCodeRegular(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumpdelete?access_token="
				+ accessToken.toString();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("prefix", "https://minipro.arvatocrm.cn/arvato/index.html");
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramMap));
	    logger.info("请求删除二维码规则的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 发布二维码的规则
	 * @param authorizerAppID
	 * @return
	 */
	public Result publishQRCodeRegular(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumppublish?access_token="
				+ accessToken.toString();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("prefix", "https://minipro.arvatocrm.cn/arvato/index.html");
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", jsonUtil.obj2String(paramMap));
	    logger.info("请求发布二维码规则的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	result.setResult(true);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
	
	/**
	 * 获取设置二维码规则的文件名称及内容
	 * 所需要的校验文件的名称及内容
	 * @param authorizerAppID
	 * @return
	 */
	public Result getCheckFile(String authorizerAppID) {
		Result result = new Result(false);
		Object accessToken = redisUtil.get(authorizerAppID);
		if(accessToken == null) {
			// 如果当前授权码已经过期 就刷新授权码
			result = refreshAuthAccessToken(authorizerAppID);
			if(result.getCode() != 200) {
				return result;
			}
			accessToken = result.getData();
		}
		String url = "https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumpdownload?access_token="
				+ accessToken.toString();
	    String respJsonStr = HttpsUtil.httpsRequest(url, "POST", "{}");
	    logger.info("请求校验文件的名称及内容的返回值：" + respJsonStr);
	    Map<String, Object> map = jsonUtil.str2Map(respJsonStr);
	    if(map != null && "0".equals(map.get("errcode").toString())) {
	    	result.setResult(true);
	    	result.setData(map);
	    }else {
	    	result.setResult(false);
	    }
		return result;
	}
}
